package com.cdsxlc.common.service.impl;

import com.cdsxlc.common.constant.GeneratorConstant;
import com.cdsxlc.common.entity.TableColumns;
import com.cdsxlc.common.enums.Template;
import com.cdsxlc.common.service.GeneratorService;
import com.cdsxlc.common.utils.FileUtils;
import com.cdsxlc.common.utils.GenerateUtils;
import com.cdsxlc.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhang
 */
@Service
public class GeneratorServiceImpl implements GeneratorService {

    private static Logger logger = LoggerFactory.getLogger(TableServiceImpl.class);

    @Override
    public void generateEntity(String className, String tableName, List<TableColumns> tableColumns, String comment) {
        logger.info("------------------>>>>开始创建实体<<<<<-------------");
        String fileContent = FileUtils.readFileText(GeneratorConstant.TEMPLATE_PATH + Template.ENTITY.getTemplateName());
        Map<String, String> map = commonComment(Template.ENTITY, className, comment);
        map.put("tableName", tableName);
        map.putAll(GenerateUtils.getEntityData(tableColumns));
        fileContent = StringUtils.replace(fileContent, map);
        this.fileWrite(Template.ENTITY, StringUtils.getClassName(className), fileContent);
        logger.info("------------------>>>>结束创建实体<<<<<<-------------");
    }

    @Override
    public void generateRepository(String className, List<TableColumns> tableColumns, String comment) {
        logger.info("------------------>>>>开始创建 repository <<<<<-------------");
        String fileContent = FileUtils.readFileText(GeneratorConstant.TEMPLATE_PATH +
                Template.REPOSITORY.getTemplateName());
        Map<String, String> map = commonComment(Template.REPOSITORY, className, comment);
        StringBuilder classNameReference = new StringBuilder("");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "entity." + className + ";\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "repository.BaseRepository;\n");
        map.put("classNameReference", classNameReference.toString());
        fileContent = StringUtils.replace(fileContent, map);
        this.fileWrite(Template.REPOSITORY, StringUtils.getClassName(className), fileContent);
        logger.info("------------------>>>>结束创建 repository <<<<<<-------------");
    }

    @Override
    public void generateService(String className, List<TableColumns> tableColumns, String comment) {
        logger.info("------------------>>>>开始创建 service <<<<<-------------");
        String fileContent = FileUtils.readFileText(GeneratorConstant.TEMPLATE_PATH +
                Template.SERVICE.getTemplateName());
        StringBuilder classNameReference = new StringBuilder("");
        Map<String, String> map = commonComment(Template.SERVICE, className, comment);
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "vo.PageVo;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "vo.ResultVo;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "entity." + className + ";\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "dto." + className + "SearchDTO;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "dto." + className + "DTO;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "vo." + className + "Vo;\n");
        map.put("classNameReference", classNameReference.toString());
        fileContent = StringUtils.replace(fileContent, map);
        this.fileWrite(Template.SERVICE, StringUtils.getClassName(className), fileContent);
        logger.info("------------------>>>>结束创建 repository <<<<<<-------------");
    }

    @Override
    public void generateServiceImpl(String className, List<TableColumns> tableColumns, String comment) {
        logger.info("------------------>>>>开始创建 service实现 <<<<<-------------");
        String fileContent = FileUtils.readFileText(GeneratorConstant.TEMPLATE_PATH +
                Template.IMPL.getTemplateName());
        Map<String, String> map = commonComment(Template.IMPL, className, comment);
        StringBuilder classNameReference = new StringBuilder("");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "vo." + className + "Vo;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "dto." + className + "SearchDTO;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "dto." + className + "DTO;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "entity." + className + ";\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "service." + className + "Service;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "repository." + className + "Repository;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "vo.PageVo;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "vo.ResultVo;\n");
        map.put("classNameReference", classNameReference.toString());
        fileContent = StringUtils.replace(fileContent, map);
        this.fileWrite(Template.IMPL, StringUtils.getClassName(className), fileContent);
        logger.info("------------------>>>>结束创建 repository <<<<<<-------------");
    }

    @Override
    public void generateDTO(String className, List<TableColumns> tableColumns, String comment) {
        logger.info("------------------>>>>开始创建 DTO <<<<<-------------");
        String fileContent = FileUtils.readFileText(GeneratorConstant.TEMPLATE_PATH +
                Template.DTO.getTemplateName());
        Map<String, String> map = commonComment(Template.DTO, className, comment);
        map.putAll(GenerateUtils.getDTOData(tableColumns));
        fileContent = StringUtils.replace(fileContent, map);
        this.fileWrite(Template.DTO, StringUtils.getClassName(className), fileContent);
        logger.info("------------------>>>>结束创建 repository <<<<<<-------------");
    }

    @Override
    public void generateVo(String className, List<TableColumns> tableColumns, String comment) {
        logger.info("------------------>>>>开始创建 Vo <<<<<-------------");
        String fileContent = FileUtils.readFileText(GeneratorConstant.TEMPLATE_PATH +
                Template.VO.getTemplateName());
        Map<String, String> map = commonComment(Template.VO, className, comment);
        map.putAll(GenerateUtils.getVoData(tableColumns));
        fileContent = StringUtils.replace(fileContent, map);
        this.fileWrite(Template.VO, StringUtils.getClassName(className), fileContent);
        logger.info("------------------>>>>结束创建 repository <<<<<<-------------");
    }

    @Override
    public void generateController(String className, List<TableColumns> tableColumns, String tableComment) {
        logger.info("------------------>>>>开始创建 controller <<<<<-------------");
        String fileContent = FileUtils.readFileText(GeneratorConstant.TEMPLATE_PATH +
                Template.CONTROLLER.getTemplateName());
        Map<String, String> map = commonComment(Template.CONTROLLER, className, tableComment);

        StringBuilder classNameReference = new StringBuilder("");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "constant.PermitAllUrl;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "dto." + className + "DTO;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "dto." + className + "SearchDTO;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "service." + className + "Service;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "valid.GroupEdit;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "vo." + className + "Vo;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "vo.PageVo;\n");
        classNameReference.append("import " + GeneratorConstant.PACKAGE_PREFIX + "vo.ResultVo;\n");
        map.put("classNameReference", classNameReference.toString());
        fileContent = StringUtils.replace(fileContent, map);
        this.fileWrite(Template.CONTROLLER, StringUtils.getClassName(className), fileContent);
        logger.info("------------------>>>>结束创建 repository <<<<<<-------------");
    }

    @Override
    public void generateSearchDTO(String className, List<TableColumns> tableColumns, String tableComment) {
        logger.info("------------------>>>>开始创建search <<<<<-------------");
        String fileContent = FileUtils.readFileText(GeneratorConstant.TEMPLATE_PATH +
                Template.SEARCH_TEMPLATE.getTemplateName());
        Map<String, String> map = commonComment(Template.SEARCH_TEMPLATE, className, tableComment);
        fileContent = StringUtils.replace(fileContent, map);
        this.fileWrite(Template.SEARCH_TEMPLATE, StringUtils.getClassName(className), fileContent);
        logger.info("------------------>>>>结束创建 开始创建search <<<<<<-------------");
    }

    /**
     * 生成文件
     */
    private void fileWrite(Template template, String className, String content) {
        String path = GeneratorConstant.WRITE_FILE_BASE_PATH + template.getTargetDirectory();
        if (template == Template.DTO || template == Template.VO || template == Template.SEARCH_TEMPLATE) {
            path = GeneratorConstant.WRITE_FILE_BASE_PATH_COMMON + template.getTargetDirectory();
        }
        FileUtils.writeContent(path,
                className + template.getSuffix(), content);

    }

    /**
     * 通用 替换字段
     *
     * @param className
     * @param classDescription
     * @return
     */
    private Map<String, String> commonComment(Template template, String className, String classDescription) {
        Map<String, String> map = new HashMap(8);
        map.put("classDescription", classDescription);
        map.put("author", GeneratorConstant.author);
        map.put("dateTime", LocalDateTime.now().toString());
        map.put("className", StringUtils.getClassName(className));
        map.put("lowerClassName", StringUtils.firstLowerCase(className));
        map.put("packagePath", template.getPackagePrefix().substring(0, template.getPackagePrefix().length() - 1));
        return map;
    }
}
